#include <iostream>
#include "httplib.h"
#include "ContactsException.h"
#include"add_contact.pb.h"

using namespace std;
// using std::cout;
// using std::endl;
// using std::cerr;
using namespace httplib;

#define CONTACTS_HOST "14.103.248.182"
#define CONTACTS_PORT 8123


void menu()
{
    std::cout << "-----------------------------------------------------" << std::endl
              << "--------------- 请选择对通讯录的操作 ----------------" << std::endl
              << "------------------ 1、新增联系人 --------------------" << std::endl
              << "------------------ 2、删除联系人 --------------------" << std::endl
              << "------------------ 3、查看联系人列表 ----------------" << std::endl
              << "------------------ 4、查看联系人详细信息 ------------" << std::endl
              << "------------------ 0、退出 --------------------------" << std::endl
              << "-----------------------------------------------------" << std::endl;
}

int main()
{
    enum OPTION
    {
        QUIT = 0,
        ADD,
        DELETE,
        FINDALL,
        FINDONE
    };
    while (1)
    {
        menu(); // 打印通讯录菜单
        cout << "请选择操作：" << endl;
        int choose;
        cin >> choose;
        cin.ignore(256, '\n');
        try
        {
            switch (choose)
            {
            case OPTION::QUIT:
                cout << "程序退出" << endl;
                return 0;
            case OPTION::ADD:
                addContact();
                break;
            case OPTION::FINDALL:
            case OPTION::FINDONE:
            case OPTION::DELETE:
                break;
            default:
                cout << "选择有误，请重新选择" << endl;
                break;
            }
        }
        catch (const ContactsException &e)
        {
            cout << "通讯录发生异常" << endl
                 << "异常原因为：" << e.what() << endl;
        }
    }

    return 0;
}

void buildAddContactRequest(add_contact::AddContactRequest* req){
    std::cout << "-------------新增联系人-------------" << std::endl;

    std::cout << "请输入联系人姓名：";
    std::string name;
    std::getline(std::cin,name);
    req->set_name(name);

    std::cout << "请输入联系人年龄：";
    int age;
    std::cin >> age;
    req->set_age(age);
    //去除换行符
    std::cin.ignore(256,'\n');

    for(int i = 0;;i++){
        std::cout << "请输入联系人电话" << i << "(只输入回车完成电话新增)：";
       std::string number;
        std::getline(std::cin,number);
        if(number.empty()){
            break;
        }

        add_contact::AddContactRequest_Phone* phone = req->add_phone();
        phone->set_phone_number(number);

        cout << "请输入该电话的类型(1.移动电话 2.固定电话)：";
        int type;
        cin >> type;
        cin.ignore(256,'\n');
        switch(type){
            case 1:
                phone->set_type(add_contact::AddContactRequest_Phone_PhoneType::AddContactRequest_Phone_PhoneType_MP);
                break;
            case 2:
                phone->set_type(add_contact::AddContactRequest_Phone_PhoneType::AddContactRequest_Phone_PhoneType_TEL);
                break;
            default:
                cout << "选择有误!" << endl;
                break;
        }

    }
    
    std::cout << "-----------添加联系人成功-----------" << std::endl;
}


void addContact()
{
    Client cli(CONTACTS_HOST,CONTACTS_PORT);
    //构造req
    add_contact::AddContactRequest req;
    buildAddContactRequest(&req);

    //序列化req
    string req_str;
    if(!req.SerializeToString(&req_str)){
        throw ContactsException("AddContactRequest序列化失败！");
    }


    //发起post调用
    auto res = cli.Post("/contacts/add",req_str,"applicaion/protobuf");
    if(!res){
        string err_desc;
        err_desc.append("/contacts/add 链接失败！错误信息：")
                .append(httplib::to_string(res.error()));
        throw ContactsException(err_desc);
    }

    //反序列化resp
    add_contact::AddContactResponse resp;
    bool parse = resp.ParseFromString(res->body);
    if(res->status != 200 && !parse){
        string err_desc;
        err_desc.append("/contacts/add 调用失败")
                .append(std::to_string(res->status))
                .append("(").append(res->reason).append(")");
        throw ContactsException(err_desc);
    }
    else if(res->status != 200){
        string err_desc;
        err_desc.append("/contacts/add 调用失败")
                .append(std::to_string(res->status))
                .append("(").append(res->reason).append(")错误原因：")
                .append(resp.error_desc());
        throw ContactsException(err_desc);
    }
    else if(!resp.success()){
        string err_desc;
        err_desc.append("/contacts/add 结果异常")
                .append("异常原因：")
                .append(resp.error_desc());
        throw ContactsException(err_desc);
    }
    //结果打印

    cout << "新增联系人成功,联系人ID:" << resp.uid() << endl;
}



// int main(){
//     Client cli(CONTACTS_HOST,CONTACTS_PORT);

//     Result res1 = cli.Post("./test-post");
//     if(res1->status == 200){
//         cout << "调用post成功!" << endl;
//     }

//     Result res2 = cli.Get("./test-Get");
//     if(res2->status == 200){
//         cout << "调用Get成功!" << endl;
//     }

//     return 0;
// }
